package org.jmc.refmanager.web.wicket.page.service;

import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow.MaskType;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.validation.validator.PatternValidator;
import org.jmc.refmanager.domain.model.OrgUnit;
import org.jmc.refmanager.domain.model.User;
import org.jmc.refmanager.domain.service.ChangeManager;
import org.jmc.refmanager.domain.service.OrgUnitManager;
import org.jmc.refmanager.domain.service.UserManager;
import org.jmc.refmanager.domain.service.exception.BusinessException;
import org.jmc.refmanager.security.SecurityHelper;
import org.jmc.refmanager.util.Util;
import org.jmc.refmanager.web.wicket.form.ServiceEditForm;
import org.jmc.refmanager.web.wicket.page.panel.SelectCodePostalPanel2;
import org.jmc.refmanager.web.wicket.page.panel.SelectParentPanel1;
import org.jmc.refmanager.web.wicket.page.search.ServicesListPage;
import org.jmc.refmanager.web.wicket.page.template.TemplatePage;

/**
 */
@AuthorizeInstantiation(value={"ROLE_MODIF", "ROLE_APPROVER"})
public class ServiceEditPage extends TemplatePage {
	@SpringBean(name="orgUnitManager")
	private OrgUnitManager orgUnitManager;

	@SpringBean(name="taskManager")
	private ChangeManager taskManager;
	
	@SpringBean(name="userManager")
	private UserManager userManager;

	/**
	 * @param parameters
	 */
	public ServiceEditPage(PageParameters parameters) {
		super(parameters);
		initComponents(parameters); 
	}

	private void initComponents(PageParameters parameters) {
		add(new Label("pageTitle", "Modification du service"));
        
		final String matricule = SecurityHelper.getAuthentication().getName();
		
		Integer id = parameters.getAsInteger("id");
		final OrgUnit editService = orgUnitManager.findById(id);

		final IModel<OrgUnit> serviceModel = new Model<OrgUnit>(editService);
		
		final RequiredTextField<String> codePostalTextField = new RequiredTextField<String>("codePostal", 
				new PropertyModel<String>(serviceModel, "codePostal"));
		codePostalTextField.setOutputMarkupId(true);
		codePostalTextField.add(new PatternValidator("[0-9]{5}"));

		final Label communeLabel = new Label("commune", 
				new PropertyModel<String>(serviceModel, "commune"));
		communeLabel.setOutputMarkupId(true);

		final ModalWindow codePostalPicker = buildCodePostalPicker();
		codePostalPicker.setContent(new SelectCodePostalPanel2(codePostalPicker.getContentId(), serviceModel) {
			private static final long serialVersionUID = 1L;

			@Override
			public void onSave(AjaxRequestTarget target) {
				target.addComponent(codePostalTextField);
				target.addComponent(communeLabel);
				codePostalPicker.close(target);
			}

			@Override
			public void onCancel(AjaxRequestTarget target) {
				codePostalPicker.close(target);
			}
		});

		// Gestion du picker de service parent
		final RequiredTextField<String> parentCodeUOTextField = new RequiredTextField<String>("parentCodeUO", 
				new PropertyModel<String>(serviceModel, "parent.codeUO"));
		parentCodeUOTextField.setOutputMarkupId(true);

		final ModalWindow parentCodeUOPicker = buildParentCodeUOPicker();
		parentCodeUOPicker.setContent(new SelectParentPanel1(parentCodeUOPicker.getContentId(), serviceModel) {
			private static final long serialVersionUID = 1L;

			@Override
			public void onSave(AjaxRequestTarget target) {
				target.addComponent(parentCodeUOTextField);
				parentCodeUOPicker.close(target);
			}
			
			@Override
			public void onCancel(AjaxRequestTarget target) {
				parentCodeUOPicker.close(target);
			}
		});
		
		// Formulaire d'edition de service
        ServiceEditForm editForm = new ServiceEditForm("editForm", new CompoundPropertyModel<OrgUnit>(serviceModel), codePostalPicker, parentCodeUOPicker) {
			private static final long serialVersionUID = 1L;

			
			@Override
			protected void onSubmit() {
				try {
					OrgUnit service = getModelObject();
					
					if (service.hasUpdates()) {
						// Appel e la couche de service
						User user = userManager.getByMatricule(matricule);
						taskManager.assignUpdateService(service, user);
						
						// Affiche le message sur la page redirigee
						getSession().info("La modification du service a été prise en compte et a été soumise à l'approbation du référent de direction.");
						setResponsePage(ServicesListPage.class);
					} else {
						getSession().info("Aucune modification de service n'a été prise en compte.");
						setResponsePage(ServicesListPage.class);
					}
				} catch (ConstraintViolationException e) {
					error("La demande de modification de service n'a pas été prise en compte.");
					Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
					for (ConstraintViolation<?> constraintViolation : violations) {
						error(constraintViolation.getMessage());
					}
					setResponsePage(ServiceEditPage.this);
				} catch (BusinessException be) {
					error(be.getMessage());
					setResponsePage(ServiceEditPage.this);
				}
			}
        };
        add(editForm);

        editForm.add(parentCodeUOPicker);
        editForm.add(codePostalPicker);

        editForm.add(new Button("btnSubmit") {
        	@Override
        	public void onSubmit() {
        		if (Util.isEmpty(codePostalTextField.getModelObject())) {
        			error("Le code postal est obligatoire");
        		} else {
        			super.onSubmit();
        		}
        	}
        });
		
		Button btnCancel = new Button("btnCancel") {
			private static final long serialVersionUID = 1L;
			@Override
			public void onSubmit() {
				// Affiche le message sur la page redirigee
        		getSession().warn("Aucune modification n'a été réalisée");
				setResponsePage(ServicesListPage.class);
			}
		};
		// Pas de validation
		btnCancel.setDefaultFormProcessing(false);
		editForm.add(btnCancel);

		editForm.add(codePostalTextField);
		editForm.add(communeLabel);

		parentCodeUOTextField.setEnabled(false);
		editForm.add(parentCodeUOTextField);
	}

	/**
	 * @return
	 */
	private ModalWindow buildCodePostalPicker() {
		final ModalWindow codePostalPicker = new ModalWindow("codePostalPicker");
//		codePostalPicker.setTitle("Choisir un code postal");
		codePostalPicker.setInitialWidth(800);
		codePostalPicker.setWidthUnit("px");
		codePostalPicker.setUseInitialHeight(true);
//		codePostalPicker.setInitialHeight(480);
		codePostalPicker.setHeightUnit("px");
		codePostalPicker.setResizable(true);
		codePostalPicker.setMaskType(MaskType.TRANSPARENT);
		return codePostalPicker;
	}

	/**
	 * @return
	 */
	private ModalWindow buildParentCodeUOPicker() {
		final ModalWindow parentCodeUOPicker = new ModalWindow("parentCodeUOPicker");
//		parentCodeUOPicker("Choisir un code postal");
		parentCodeUOPicker.setInitialWidth(800);
		parentCodeUOPicker.setWidthUnit("px");
		parentCodeUOPicker.setUseInitialHeight(true);
//		parentCodeUOPicker.setInitialHeight(480);
		parentCodeUOPicker.setHeightUnit("px");
		parentCodeUOPicker.setResizable(true);
		parentCodeUOPicker.setMaskType(MaskType.TRANSPARENT);
		return parentCodeUOPicker;
	}

}

